﻿using System;
using System.Globalization;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

namespace Web7.Utilities
{
    /// <summary>
    /// 
    /// </summary>
    public class WebUtils
    {
        public static readonly Regex _fileComponentTextToEscape = new Regex(@"([^A-Za-z0-9 ]+|\.| )", RegexOptions.Singleline | RegexOptions.Compiled);
        public static readonly Regex _fileComponentTextToUnescape = new Regex(@"((?:_(?:[0-9a-f][0-9a-f][0-9a-f][0-9a-f])+_)|_|\-)", RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
        public static readonly Regex _pathComponentTextToEscape = new Regex(@"([^A-Za-z0-9\- ]+|\.| )", RegexOptions.Singleline | RegexOptions.Compiled);
        public static readonly Regex _pathComponentTextToUnescape = new Regex(@"((?:_(?:[0-9a-f][0-9a-f][0-9a-f][0-9a-f])+_)|\+)", RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
        public static readonly string HtmlNewLine = "<br />";

        /// <summary>
        /// 
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public static string FormatCompleteUrl(string content, string url)
        {
            string pattern = "src=[\"']\\s*(/[^\"']*)\\s*[\"']";
            string str2 = "href=[\"']\\s*(/[^\"']*)\\s*[\"']";
            string str3 = HostPath(HttpContext.Current.Request.Url);
            content = Regex.Replace(content, pattern, string.Format("src=\"{0}$1\"", url), RegexOptions.Compiled | RegexOptions.IgnoreCase);
            content = Regex.Replace(content, str2, string.Format("href=\"{0}$1\"", url), RegexOptions.Compiled | RegexOptions.IgnoreCase);
            return content;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="absoluteUrl"></param>
        /// <returns></returns>
        public static string FullPath(string absoluteUrl)
        {
            if (absoluteUrl.StartsWith("http", StringComparison.CurrentCultureIgnoreCase))
            {
                return absoluteUrl;
            }
            return FullPath(HostPath(HttpContext.Current.Request.Url), absoluteUrl);
        }

        /// <summary>
        /// 获取完整路径
        /// </summary>
        /// <param name="hostPath"></param>
        /// <param name="absoluteUrl"></param>
        /// <returns></returns>
        public static string FullPath(string hostPath, string absoluteUrl)
        {
            return (hostPath + absoluteUrl);
        }

        /// <summary>
        /// 获取http头属性
        /// </summary>
        /// <param name="headerValue"></param>
        /// <param name="attrName"></param>
        /// <returns></returns>
        public static string GetAttributeFromHeader(string headerValue, string attrName)
        {
            int index;
            if (headerValue == null)
            {
                return null;
            }
            int length = headerValue.Length;
            int num3 = attrName.Length;
            int startIndex = 1;
            while (startIndex < length)
            {
                startIndex = CultureInfo.InvariantCulture.CompareInfo.IndexOf(headerValue, attrName, startIndex, CompareOptions.IgnoreCase);
                if ((startIndex < 0) || ((startIndex + num3) >= length))
                {
                    break;
                }
                char c = headerValue[startIndex - 1];
                char ch2 = headerValue[startIndex + num3];
                if ((((c == ';') || (c == ',')) || char.IsWhiteSpace(c)) && ((ch2 == '=') || char.IsWhiteSpace(ch2)))
                {
                    break;
                }
                startIndex += num3;
            }
            if ((startIndex < 0) || (startIndex >= length))
            {
                return null;
            }
            startIndex += num3;
            while ((startIndex < length) && char.IsWhiteSpace(headerValue[startIndex]))
            {
                startIndex++;
            }
            if ((startIndex >= length) || (headerValue[startIndex] != '='))
            {
                return null;
            }
            startIndex++;
            while ((startIndex < length) && char.IsWhiteSpace(headerValue[startIndex]))
            {
                startIndex++;
            }
            if (startIndex >= length)
            {
                return null;
            }
            if ((startIndex < length) && (headerValue[startIndex] == '"'))
            {
                if (startIndex == (length - 1))
                {
                    return null;
                }
                index = headerValue.IndexOf('"', startIndex + 1);
                if ((index < 0) || (index == (startIndex + 1)))
                {
                    return null;
                }
                return headerValue.Substring(startIndex + 1, (index - startIndex) - 1).Trim();
            }
            index = startIndex;
            while (index < length)
            {
                if (((headerValue[index] == ' ') || (headerValue[index] == ',')) || (headerValue[index] == ';'))
                {
                    break;
                }
                index++;
            }
            if (index == startIndex)
            {
                return null;
            }
            return headerValue.Substring(startIndex, index - startIndex).Trim();
        }

        /// <summary>
        /// 获取文件路径
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static string GetPhysicalFilePath(string filePath)
        {
            string str = null;
            if ((filePath.IndexOf(@":\") != -1) || (filePath.IndexOf(@"\\") != -1))
            {
                str = filePath;
            }
            else
            {
                HttpContext current = HttpContext.Current;
                if (current != null)
                {
                    str = current.Server.MapPath(filePath);
                }
                else
                {
                    filePath = filePath.Replace('/', Path.DirectorySeparatorChar).Replace("~", "");
                    return (AppDomain.CurrentDomain.BaseDirectory.Replace('/', Path.DirectorySeparatorChar).TrimEnd(new char[] { Path.DirectorySeparatorChar }) + Path.DirectorySeparatorChar.ToString() + filePath.TrimStart(new char[] { Path.DirectorySeparatorChar }));
                }
            }
            if (!str.EndsWith(Path.DirectorySeparatorChar.ToString()))
            {
                str = str + Path.DirectorySeparatorChar;
            }
            return str;
        }

        /// <summary>
        /// 获取用户IP
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetUserIpAddress(HttpContext context)
        {
            string userHostAddress = string.Empty;
            if (context != null)
            {
                userHostAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

                if (string.IsNullOrEmpty(userHostAddress))
                {
                    userHostAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
                }
                if ((userHostAddress == null) || (userHostAddress == string.Empty))
                {
                    userHostAddress = HttpContext.Current.Request.UserHostAddress;
                }
            }
            return userHostAddress;
        }

        /// <summary>
        /// 获取应用程序URL
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        public static string HostPath(Uri uri)
        {
            string str = (uri.Port == 80) ? string.Empty : (":" + uri.Port.ToString());
            return string.Format("{0}://{1}{2}", uri.Scheme, uri.Host, str);
        }

        /// <summary>
        /// HTML解码
        /// </summary>
        /// <param name="textToFormat"></param>
        /// <returns></returns>
        public static string HtmlDecode(string textToFormat)
        {
            if (string.IsNullOrEmpty(textToFormat))
            {
                return textToFormat;
            }
            return HttpUtility.HtmlDecode(textToFormat);
        }

        /// <summary>
        /// HTML编码
        /// </summary>
        /// <param name="textToFormat"></param>
        /// <returns></returns>
        public static string HtmlEncode(string textToFormat)
        {
            if (string.IsNullOrEmpty(textToFormat))
            {
                return textToFormat;
            }
            return HttpUtility.HtmlEncode(textToFormat);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="url"></param>
        public static void Redirect301(HttpContext context, string url)
        {
            context.Response.Clear();
            context.Response.StatusCode = 0x12d;
            context.Response.AppendHeader("location", url);
            context.Response.End();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="relativeUrl"></param>
        /// <returns></returns>
        public static string ResolveUrl(string relativeUrl)
        {
            if (!string.IsNullOrEmpty(relativeUrl) && relativeUrl.StartsWith("~/"))
            {
                string[] strArray = relativeUrl.Split(new char[] { '?' });
                string str = VirtualPathUtility.ToAbsolute(strArray[0]);
                if (strArray.Length > 1)
                {
                    str = str + "?" + strArray[1];
                }
                return str;
            }
            return relativeUrl;
        }

        /// <summary>
        /// 304错误
        /// </summary>
        /// <param name="context"></param>
        public static void Return304(HttpContext context)
        {
            context.Response.Clear();
            context.Response.StatusCode = 0x130;
            context.Response.Status = "304 Not Modified";
            context.Response.End();
        }

        /// <summary>
        /// 404错误
        /// </summary>
        /// <param name="context"></param>
        public static void Return404(HttpContext context)
        {
            context.Response.Clear();
            context.Response.StatusCode = 0x194;
            context.Response.SuppressContent = true;
            context.Response.End();
        }

        /// <summary>
        /// URL解密
        /// </summary>
        /// <param name="urlToDecode"></param>
        /// <returns></returns>
        public static string UrlDecode(string urlToDecode)
        {
            if (string.IsNullOrEmpty(urlToDecode))
            {
                return urlToDecode;
            }
            return HttpUtility.UrlDecode(urlToDecode);
        }

        /// <summary>
        /// URL解密
        /// </summary>
        /// <param name="text"></param>
        /// <param name="pattern"></param>
        /// <returns></returns>
        private static string UrlDecode(string text, Regex pattern)
        {
            if (string.IsNullOrEmpty(text))
            {
                return text;
            }
            Match match = pattern.Match(text);
            StringBuilder builder = new StringBuilder();
            int startIndex = 0;
            while (match.Value != string.Empty)
            {
                if (startIndex != match.Index)
                {
                    builder.Append(text.Substring(startIndex, match.Index - startIndex));
                }
                if (match.Value.Length == 1)
                {
                    builder.Append(" ");
                }
                else
                {
                    byte[] bytes = new byte[(match.Value.Length - 2) / 2];
                    for (int i = 1; i < (match.Value.Length - 1); i += 2)
                    {
                        bytes[(i - 1) / 2] = byte.Parse(match.Value.Substring(i, 2), NumberStyles.AllowHexSpecifier);
                    }
                    builder.Append(Encoding.Unicode.GetString(bytes));
                }
                startIndex = match.Index + match.Length;
                match = pattern.Match(text, startIndex);
            }
            if (startIndex < text.Length)
            {
                builder.Append(text.Substring(startIndex));
            }
            return builder.ToString();
        }

        /// <summary>
        /// URL文件解密
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static string UrlDecodeFileComponent(string text)
        {
            return UrlDecode(text, _fileComponentTextToUnescape);
        }

        /// <summary>
        /// URL路径解密
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static string UrlDecodePathComponent(string text)
        {
            return UrlDecode(text, _pathComponentTextToUnescape);
        }

        /// <summary>
        /// URL解密
        /// </summary>
        /// <param name="urlToEncode"></param>
        /// <returns></returns>
        public static string UrlEncode(string urlToEncode)
        {
            if (string.IsNullOrEmpty(urlToEncode))
            {
                return urlToEncode;
            }
            return HttpUtility.UrlEncode(urlToEncode).Replace("'", "%27");
        }

        /// <summary>
        /// URL加密
        /// </summary>
        /// <param name="text"></param>
        /// <param name="pattern"></param>
        /// <param name="spaceReplacement"></param>
        /// <param name="escapePrefix"></param>
        /// <returns></returns>
        private static string UrlEncode(string text, Regex pattern, char spaceReplacement, char escapePrefix)
        {
            if (string.IsNullOrEmpty(text))
            {
                return text;
            }
            Match match = pattern.Match(text);
            StringBuilder builder = new StringBuilder();
            int startIndex = 0;
            while (match.Value != string.Empty)
            {
                if (startIndex != match.Index)
                {
                    builder.Append(text.Substring(startIndex, match.Index - startIndex));
                }
                if (match.Value == " ")
                {
                    builder.Append(spaceReplacement);
                }
                else if ((match.Value == ".") && (match.Index != (text.Length - 1)))
                {
                    builder.Append(".");
                }
                else
                {
                    builder.Append(escapePrefix);
                    byte[] bytes = Encoding.Unicode.GetBytes(match.Value);
                    if (bytes != null)
                    {
                        foreach (byte num2 in bytes)
                        {
                            string str = num2.ToString("X");
                            if (str.Length == 1)
                            {
                                builder.Append("0");
                            }
                            builder.Append(str);
                        }
                    }
                    builder.Append(escapePrefix);
                }
                startIndex = match.Index + match.Length;
                match = pattern.Match(text, startIndex);
            }
            if (startIndex < text.Length)
            {
                builder.Append(text.Substring(startIndex));
            }
            return builder.ToString();
        }

        /// <summary>
        /// URL文件加密
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static string UrlEncodeFileComponent(string text)
        {
            return UrlEncode(text, _fileComponentTextToEscape, '-', '_');
        }

        /// <summary>
        /// URL路径加密
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static string UrlEncodePathComponent(string text)
        {
            return UrlEncode(text, _pathComponentTextToEscape, '+', '_');
        }

        /// <summary>
        /// 获取应用程序跟路径
        /// </summary>
        public static string ApplicationPath
        {
            get
            {
                string applicationPath = "/";
                if (HttpContext.Current != null)
                {
                    applicationPath = HttpContext.Current.Request.ApplicationPath;
                }
                if (applicationPath == "/")
                {
                    return string.Empty;
                }
                return applicationPath;
            }
        }

        /// <summary>
        /// 获取用户IP
        /// </summary>
        public static string IPAddress
        {
            get
            {
                string userIpAddress = "000.000.000.000";
                HttpContext current = HttpContext.Current;
                if (current != null)
                {
                    userIpAddress = GetUserIpAddress(current);
                }
                return userIpAddress;
            }
        }

    }
}
